#ifndef _LISTE
#define _LISTE

/* Inclusion des modules utilises par le module Liste */
/* (A l'exclusion de ceux qui sont seulement utilises dans l'implantation : */
/* ceux la sont inclus dans le fichier d'implantation) */

#include <stdio.h>
#include <stdlib.h>

 typedef void * Element;

typedef struct _Cellule
{
  Element info;
  struct _Cellule *suivant;
} Cellule;

typedef struct _Liste
{
  Cellule *adPremier;
  Cellule *adDernier;
  Cellule *adCourant;
  int nb_elem;
  int positionCourant;
  void (*initialisation)(Element *, const Element);
  void (*suppression)(Element *);
  void (*afficher)(const Element);
  int (*comparaison)(const Element, const Element);
} Liste;


void initialise_Liste(Liste *l,
		      void (*initialisation)(Element *, const Element),
		      void (*suppression)(Element *),
		      void (*afficher)(const Element),
		      int (*comparaison)(const Element, const Element)
		      );
/* Precondition : *l non prealablement initialisee */
/* Postcondition : la liste *l initialisee est vide */

void initialiseCopie_Liste(Liste *l1, const Liste *l2);
/* Precondition : *l1 non prealablement initialisee,  */
/*                l2 prealablement initialisee et manipulee uniquement */
/*                a travers les operations du module  */
/* Postcondition : la liste *l1 initialisee correspond a une copie de l2 */
/*  (mais les 2 listes sont totalement independantes l'une de l'autre) */

void testament_Liste(Liste *l);
/* Precondition : *l prealablement initialisee et manipulee uniquement */
/*                a travers les operations du module */
/* Postcondition : *l prete a etre detruite */

void affectation_Liste(Liste *l1, const Liste *l2);
/*Precondition : *l1 et l2 prealablement initialisees et manipulees */
/*               uniquement a travers les operations du module */
/* Postcondition : la liste *l1 correspond a une copie de l2 */
/*  (mais les 2 listes sont totalement independantes l'une de l'autre) */

int testEstVide_Liste(Liste *l);
/* Precondition : l prealablement initialisee et manipulee uniquement */
/*                a travers les operations du module */
/* Resultat : 1 si l est vide, 0 sinon */

void suppressionEnTete_Liste(Liste *l);
/* Precondition : testListeVide(*l)==false */
/* Postcondition : la liste *l perd son premier element */

void suppressionCourant_Liste(Liste *l);
/* Supprime le courant */

void suppressionEnQueue_Liste(Liste *l);
/* Supprime le dernier */

void vide_Liste(Liste *l);
/* Precondition : aucune  */
/*                (*l initialisee et manipulee uniquement a travers les  */
/*                 operations du module) */
/* Postcondition : testlisteVide(l)==true */

void insereEnQueue_Liste(Element e , Liste *l);
/* Precondition : *l et e initialises et manipules uniquement a travers les  */
/*                 operations de leurs modules respectifs */
/* Precondition : L'Elem e est ajoute en fin de la liste *l */

void insereCourant_Liste(Element e , Liste *l);
/* Insere avant le courant */

void insereEnTete_Liste(Element e , Liste *l);
/* Insere en tete */

void affiche_Liste(const Liste *l);
/* Affiche la liste */

int chercheElem_Liste(const Element e, Liste *l);
/* Cherche l'element e dans la liste */

Element getDataCourant_Liste(const Liste *l);
/* Return l'element du courant ou NULL*/

Element getDataEnTete_Liste(const Liste *l);
/* Retourne l'element de la tete de liste ou NULL */

Element getDataEnQueue_Liste(const Liste *l);
/* Retourne l'element de la queue de liste ou NULL */

Element getDataIndice_Liste(Liste *l, const int indice);
/* Retourne l'element à l'indice donnée ou NULL */

int getIndiceData_Liste(const Element e, Liste *l);

void premier_Liste(Liste *l);
/* Met dans le courant le premier noeud de la liste */

int suivant_Liste(Liste *l);
/* Avance le courant
   return 0 quand le courant = NULL
   return 1 quand le courant = courant->suivant
   return -1 quand le courant était = NULL, le courant devient egale au premier noeud de la liste */

int insereIndice_Liste(const Element e, Liste *l, const int indice);
int suppressionIndice_Liste(Liste *l, const int indice);
#endif
